package com.olive.config;

import java.util.HashMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import com.olive.filter.AuthenticationLoggingFilter;
import com.olive.filter.RequestValidationFilter;
import com.olive.handler.CommonLoginFailureHandler;
import com.olive.handler.CommonLoginSuccessHandler;
import com.olive.service.impl.UserDetailsServiceImpl;

//@RequiredArgsConstructor
@Configuration
@EnableAsync
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
	
	@Autowired
	private UserDetailsServiceImpl commonUserDetailServiceImpl;
	
	@Autowired
	private CommonLoginSuccessHandler successHandler;
	
	@Autowired
	private CommonLoginFailureHandler failureHandler;
	
	@Autowired
	private AuthenticationLoggingFilter authenticationLoggingFilter;
	
	@Autowired
	private RequestValidationFilter requestValidationFilter;
	
//	private final UserDetailsServiceImpl commonUserDetailServiceImpl;
//	
//	private final CommonLoginSuccessHandler successHandler;
//	
//	private final CommonLoginFailureHandler failureHandler;

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.addFilterBefore(requestValidationFilter, BasicAuthenticationFilter.class)
        	.addFilterAfter(authenticationLoggingFilter, BasicAuthenticationFilter.class)
        	.csrf().disable()
                .logout()
                .and()
				.formLogin()
				.successHandler(successHandler)
				.failureHandler(failureHandler)
				.and().httpBasic().and()
				.authorizeRequests()
				.antMatchers("/login", "/user/create").permitAll()
				.anyRequest().authenticated();
	}

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(commonUserDetailServiceImpl)
				.passwordEncoder(passwordEncoder());
	}


	@Bean
	public PasswordEncoder passwordEncoder() {
		HashMap<String, PasswordEncoder> encoders = new HashMap<>();
		encoders.put("noop", NoOpPasswordEncoder.getInstance());
		encoders.put("bcrypt", new BCryptPasswordEncoder());
		encoders.put("scrypt", new SCryptPasswordEncoder());
		return new DelegatingPasswordEncoder("bcrypt", encoders);
	}
}

